import 'dart:io';
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:path/path.dart' as path;
import '../AI/tina_dart/BaseAPI.dart';
import 'file_serve.dart';
import '../AI/dify_datasets.dart';
import '../AI/screen_shot_serve.dart';
import 'tag_analysis_service.dart';

/// 上传任务状态
enum UploadStatus {
  waiting,          // 等待上传
  uploading,        // 正在上传
  pendingCategory,  // 等待用户确认分类
  success,          // 上传成功
  failed,           // 上传失败
}

/// 上传任务
class UploadTask {
  final String id;
  final String fileName;
  final String filePath;
  final String type; // 'document', 'image', 'photo'
  UploadStatus status;
  String? category;
  String? suggestedCategory; // AI建议的分类
  String? displayName; // 显示名称（用于OCR文档的标题）
  String? actualDocumentPath; // OCR处理后的实际文档路径
  String? errorMessage;
  double progress;
  DateTime createdAt;

  UploadTask({
    required this.id,
    required this.fileName,
    required this.filePath,
    required this.type,
    this.status = UploadStatus.waiting,
    this.category,
    this.suggestedCategory,
    this.displayName,
    this.actualDocumentPath,
    this.errorMessage,
    this.progress = 0.0,
    DateTime? createdAt,
  }) : createdAt = createdAt ?? DateTime.now();

  /// 获取显示的文件名
  String get effectiveFileName => displayName ?? fileName;
}

/// 全局上传服务
class UploadService extends ChangeNotifier {
  static final UploadService _instance = UploadService._internal();
  factory UploadService() => _instance;
  UploadService._internal();

  final List<UploadTask> _uploadTasks = [];
  bool _isInitialized = false;
  
  // 添加成功上传回调
  VoidCallback? _onUploadSuccess;

  // 依赖服务
  BaseAPI? _llm;
  FileServe? _fileServe;
  DifyKnowledgeDatabase? _difyKnowledge;
  String? _appDataDir;
  ScreenShotServe? _screenShotServe;
  TagAnalysisService? _tagAnalysisService;

  List<UploadTask> get uploadTasks => List.unmodifiable(_uploadTasks);
  bool get isInitialized => _isInitialized;

  /// 初始化服务
  void initialize({
    required BaseAPI llm,
    required FileServe fileServe,
    required DifyKnowledgeDatabase difyKnowledge,
    required String appDataDir,
    ScreenShotServe? screenShotServe,
    VoidCallback? onUploadSuccess,
  }) {
    _llm = llm;
    _fileServe = fileServe;
    _difyKnowledge = difyKnowledge;
    _appDataDir = appDataDir;
    _screenShotServe = screenShotServe;
    _onUploadSuccess = onUploadSuccess;
    
    // 初始化标签分析服务
    _tagAnalysisService = TagAnalysisService();
    _tagAnalysisService!.initialize(
      llm: llm,
      fileServe: fileServe,
      appDataDir: appDataDir,
    );
    
    _isInitialized = true;
  }

  /// 添加文档上传任务
  String addDocumentUploadTask(String filePath) {
    if (!_isInitialized) throw Exception('UploadService not initialized');
    
    final task = UploadTask(
      id: DateTime.now().millisecondsSinceEpoch.toString(),
      fileName: path.basename(filePath),
      filePath: filePath,
      type: 'document',
    );

    _uploadTasks.add(task);
    notifyListeners();

    // 开始处理任务
    _processDocumentUpload(task);
    
    return task.id;
  }

  /// 添加图片上传任务
  String addImageUploadTask(String filePath, String type) {
    if (!_isInitialized) throw Exception('UploadService not initialized');
    
    final task = UploadTask(
      id: DateTime.now().millisecondsSinceEpoch.toString(),
      fileName: path.basename(filePath),
      filePath: filePath,
      type: type, // 'image' or 'photo'
    );

    _uploadTasks.add(task);
    notifyListeners();

    // 开始处理任务
    _processImageUpload(task);
    
    return task.id;
  }

  /// 处理文档上传
  Future<void> _processDocumentUpload(UploadTask task) async {
    try {
      _updateTask(task, status: UploadStatus.uploading, progress: 0.1);

      // 先将文档复制到目标位置
      final docDir = Directory(path.join(_appDataDir!, 'doc'));
      if (!await docDir.exists()) {
        await docDir.create(recursive: true);
      }
      final destFile = File(path.join(docDir.path, task.fileName));
      await File(task.filePath).copy(destFile.path);
      
      _updateTask(task, progress: 0.3);

      // 获取所有分类标签
      List<String> categories = await _fileServe!.getCategories();
      _updateTask(task, progress: 0.5);

      // 询问大模型对文档进行分类建议
      final classifyResult = await _llm!.predict(
        sysPrompt: '你现在是一个文档分类助手，请根据文档的标题，将其分类到最适合的类别中。',
        inputText: '请将文档 "${task.fileName}" 分类到以下类别中的一个：${categories.join("、")}，如果里面有不符合的类别，你可以回复一个新的更加符合的类别，只需回复类别名称，不要添加其他内容。',
      );

      var suggestedCategory = classifyResult['content'].toString().trim();
      
      // 更新任务状态为等待用户确认分类
      _updateTask(task, 
        status: UploadStatus.pendingCategory, 
        suggestedCategory: suggestedCategory,
        progress: 0.8
      );

      print('UploadService: 文档上传完成，等待用户确认分类 - ${task.fileName}，建议分类: $suggestedCategory');

    } catch (e) {
      _updateTask(task, 
        status: UploadStatus.failed, 
        errorMessage: e.toString()
      );
    }
  }

  /// 处理图片上传
  Future<void> _processImageUpload(UploadTask task) async {
    try {
      _updateTask(task, status: UploadStatus.uploading, progress: 0.1);

      if (_screenShotServe == null) {
        throw Exception('OCR服务未初始化');
      }

      _updateTask(task, progress: 0.3);

      // OCR识别
      final result = await _screenShotServe!.processScreenshot(task.filePath);
      _updateTask(task, progress: 0.6);

      if (result['success']) {
        // 文档已经在processScreenshot中保存，获取保存的文档路径
        final docFilePath = result['doc_file'];
        final title = result['title'];
        
        // 获取所有分类标签
        List<String> categories = await _fileServe!.getCategories();
        
        // 请求LLM对OCR内容进行分类建议
        final classifyResult = await _llm!.predict(
          sysPrompt: '你现在是一个文档分类助手，请根据文档的标题和内容摘要，将其分类到最适合的类别中。',
          inputText: '请将标题为"${title}"，摘要内容为"${result['summary']}"的文档分类到以下类别中的一个：${categories.join("、")}，如果里面没有符合的类别，你可以回复一个新的更加符合的类别，只需回复类别名称，不要添加其他内容。',
        );
        
        var suggestedCategory = classifyResult['content'].toString().trim();
        
        // 获取实际的.md文件名（包含正确的扩展名）
        final actualFileName = path.basename(docFilePath);
        
        // 更新任务状态为等待用户确认分类，使用实际的.md文件名和路径
        task.displayName = actualFileName; // 使用实际的.md文件名
        task.actualDocumentPath = docFilePath; // 存储实际的OCR文档路径
        _updateTask(task, 
          status: UploadStatus.pendingCategory, 
          suggestedCategory: suggestedCategory,
          progress: 0.8
        );

        print('UploadService: OCR文档处理完成，等待用户确认分类 - $title，建议分类: $suggestedCategory');

      } else {
        throw Exception(result['message'] ?? 'OCR识别失败');
      }

    } catch (e) {
      _updateTask(task, 
        status: UploadStatus.failed, 
        errorMessage: e.toString()
      );
    }
  }

  /// 更新任务状态
  void _updateTask(UploadTask task, {
    UploadStatus? status,
    String? category,
    String? suggestedCategory,
    String? displayName,
    String? errorMessage,
    double? progress,
  }) {
    if (status != null) task.status = status;
    if (category != null) task.category = category;
    if (suggestedCategory != null) task.suggestedCategory = suggestedCategory;
    if (displayName != null) task.displayName = displayName;
    if (errorMessage != null) task.errorMessage = errorMessage;
    if (progress != null) task.progress = progress;
    
    notifyListeners();
  }

  /// 清理已完成的任务
  void clearCompletedTasks() {
    _uploadTasks.removeWhere((task) => 
      task.status == UploadStatus.success || task.status == UploadStatus.failed);
    notifyListeners();
  }

  /// 获取指定状态的任务数量
  int getTaskCountByStatus(UploadStatus status) {
    return _uploadTasks.where((task) => task.status == status).length;
  }

  /// 检查是否有成功的上传
  bool hasSuccessfulUploads() {
    return _uploadTasks.any((task) => task.status == UploadStatus.success);
  }

  /// 获取正在进行的任务数量
  int get activeTasksCount {
    return _uploadTasks.where((task) => 
      task.status == UploadStatus.waiting || task.status == UploadStatus.uploading
    ).length;
  }

  /// 获取等待分类确认的任务
  List<UploadTask> get pendingCategoryTasks {
    return _uploadTasks.where((task) => task.status == UploadStatus.pendingCategory).toList();
  }

  /// 用户确认文档分类
  Future<void> confirmDocumentCategory(String taskId, String finalCategory) async {
    try {
      final task = _uploadTasks.firstWhere((t) => t.id == taskId);
      
      _updateTask(task, status: UploadStatus.uploading, progress: 0.8);

      // 确定最终分类
      final category = finalCategory.trim();
      String documentPath;
      String documentName;
      
      // 判断是普通文档还是OCR文档
      if (task.type == 'document') {
        // 普通文档
        final docDir = Directory(path.join(_appDataDir!, 'doc'));
        documentPath = path.join(docDir.path, task.fileName);
        documentName = task.fileName;
      } else {
        // OCR文档，使用保存的实际文档路径
        if (task.actualDocumentPath != null && task.actualDocumentPath!.isNotEmpty) {
          // 使用OCR处理时保存的实际文档路径
          documentPath = task.actualDocumentPath!;
          documentName = task.displayName ?? path.basename(documentPath);
        } else {
          // 回退方案：重新构建路径
          final docDir = Directory(path.join(_appDataDir!, 'doc'));
          documentName = task.displayName ?? task.fileName;
          documentPath = path.join(docDir.path, documentName);
        }
      }
      
      // 添加文档到知识库
      await _fileServe!.addDocument(documentPath, category);
      
      _updateTask(task, progress: 0.9);

      // 使用Dify知识库API添加文档
      final uploadResult = await _difyKnowledge!.addDocuments(documentPath);

      // 从Dify响应中获取文档ID
      final difyDocId = uploadResult?["document"]?["id"] ?? "unknown_id";

      // 更新本地文档ID为Dify返回的ID
      await _fileServe!.updateDocumentId(
        documentPath,
        'temp_${DateTime.now().millisecondsSinceEpoch}',
        difyDocId,
      );

      _updateTask(task, 
        status: UploadStatus.success, 
        category: category,
        progress: 1.0
      );

      // 启动后台标签分析任务
      if (_tagAnalysisService != null) {
        print('UploadService: 启动文档标签分析任务 - $documentName');
        _tagAnalysisService!.addDocumentTagAnalysis(
          documentPath: documentPath,
          documentName: documentName,
          category: category,
        );
      }

      // 通知上传成功
      if (_onUploadSuccess != null) {
        _onUploadSuccess!();
      }

      print('UploadService: 文档分类确认完成 - $documentName，最终分类: $category');

    } catch (e) {
      final task = _uploadTasks.firstWhere((t) => t.id == taskId);
      _updateTask(task, 
        status: UploadStatus.failed, 
        errorMessage: e.toString()
      );
      print('UploadService: 文档分类确认失败 - ${task.effectiveFileName}: $e');
    }
  }
} 